package cn.cocho.dborm.core;

import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.Date;

import net.sqlcipher.Cursor;

/**
 * 数据库的数据与Java数据的转换器
 * 
 * @author dborm@cocho
 * @time 2013-5-6下午12:01:06
 */
public class DataTypeConverter {

	/**
	 * 一定不能支持基本数值类型，如支持Integer但是不能支持int，原因如下：<br>
	 * 1.replace的原则是忽略null字段<br>
	 * 2.数据库取出的值未必会有值，没有值的时候应该对属性的初始值赋值为null
	 * 
	 */
	private static final String SUPPORT_TYPE = "only supported[String, Integer, Boolean, Date, Long, Float, Double, Short, Byte]";

	/**
	 * 将Java属性类型的值转换为数据列对应的值
	 * 
	 * @param fieldValue
	 *            Java类型的参数值
	 * @return 数据列的值
	 * @author dborm@cocho
	 * @time 2013-5-5上午2:36:18
	 */
	public static Object fieldValueToColumnValue(Object fieldValue) {
		if (fieldValue == null) {
			return null;
		}

		if (Date.class.equals(fieldValue.getClass())) {
			Date time = (Date) fieldValue;
			return time.getTime();
		}
		return fieldValue;
	}

	/**
	 * 将数据列对应的值转换为Java属性类型的值
	 * 
	 * @param cursor
	 *            结果集
	 * @param columnName
	 *            列名称
	 * @param field
	 *            属性对象
	 * @return 该属性类型的值
	 * @throws SQLException
	 * @author dborm@cocho
	 * @time 2013-5-5上午2:44:02
	 */
	public static Object columnValueToFieldValue(Cursor cursor, String columnName, Field field) throws SQLException {
		Class<?> type = field.getType();
		int columnIndex = cursor.getColumnIndex(columnName);
		if (cursor.isNull(columnIndex)) {
			return null;
		}
		try {
			if (isString(type)) {
				return cursor.getString(columnIndex);
			} else if (isInteger(type)) {
				return cursor.getInt(columnIndex);
			} else if (isBoolean(type)) {
				return cursor.getShort(columnIndex) > 0;
			} else if (isDate(type)) {
				long time = cursor.getLong(columnIndex);
				return new Date(time);
			} else if (isLong(type)) {
				return cursor.getLong(columnIndex);
			} else if (isFloat(type)) {
				return cursor.getFloat(columnIndex);
			} else if (isDouble(type)) {
				return cursor.getDouble(columnIndex);
			} else if (isShort(type)) {
				return cursor.getShort(columnIndex);
			} else if (isByte(type)) {
				return cursor.getBlob(columnIndex);
			} else {
				throw new UnsupportedOperationException("类[" + field.getDeclaringClass() + "]中的属性[" + field.getName() + "] 的类型名称为["
						+ type.getName() + "] 暂不支持!\n 暂时支持的类型名称：" + SUPPORT_TYPE);
			}
		} catch (Exception e) {
			throw new RuntimeException("将列名为[" + columnName + "] 的值转换为属性名为[" + field.getName() + "]的值时出错!", e);
		}
	}

	private static boolean isString(Class<?> type) {
		return String.class.equals(type);
	}

	private static boolean isInteger(Class<?> type) {
		return Integer.class.equals(type);
	}

	private static boolean isBoolean(Class<?> type) {
		return Boolean.class.equals(type);
	}

	private static boolean isFloat(Class<?> type) {
		return Float.class.equals(type);
	}

	private static boolean isLong(Class<?> type) {
		return Long.class.equals(type);
	}

	private static boolean isDouble(Class<?> type) {
		return Double.class.equals(type);
	}

	private static boolean isDate(Class<?> type) {
		return Date.class.equals(type);
	}

	private static boolean isShort(Class<?> type) {
		return Short.class.equals(type);
	}

	private static boolean isByte(Class<?> type) {
		return type.isArray() && (type.getComponentType().equals(byte.class) || type.getComponentType().equals(Byte.class));
	}

}
